package com.yfl;

import com.yfl.util.GenUtils;
import org.apache.commons.io.IOUtils;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.*;
import java.util.*;
import java.util.zip.ZipOutputStream;

/**
 * @author 袁飞龙(617823298)
 * @create 2017年12月19日
 */
public class CodeGenerator {

//    private static String schema = "user-central" ;
    private static final String driverClassName = "com.mysql.cj.jdbc.Driver" ;
    private static String url = "jdbc:mysql://ip:port/schema?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai" ;
    //    private static final String url = "jdbc:mysql://120.79.198.159:3306/wzry?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false";
    private static String username = "root" ;
    private static String password = "qwe123" ;

    //    private static final String password = "MyNewPass4!";
    private static Connection conn = null;

    static {
        try {
            Class.forName(driverClassName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        if(args.length < 5){
            System.err.println("please check input params format: username password ip:port schema basePackage");
            return;
        }
        username = args[0];
        password = args[1];
        String schema = args[3];
        url = "jdbc:mysql://"+args[2]+"/"+schema+"?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai";
        String basePackage = args[4];
        List<String> tables = queryAllTable(schema);
//        Iterator<String> iterable = tables.iterator();
//        while (iterable.hasNext()) {
//            String table = iterable.next();
//            table = table.replace("t_","");
//            if (!table.contains("t")) {
//                iterable.remove();
//            }
//        }
        String[] tableNames = (String[]) tables.toArray(new String[0]);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        for (String table : tableNames) {
            Map<String, String> tableDetail = queryTableDetailByTable(schema , table);
            //查询列信息
            List<Map<String, String>> columns = queryColumns(schema , table);
            //生成代码
            GenUtils.generatorCode(tableDetail, columns, zip, "/spring-boot-data-jpa",basePackage);
        }
        zip.close();
        byte[] bytes = outputStream.toByteArray();
        FileOutputStream fos = new FileOutputStream("D:\\code.zip" );
        fos.flush();
        IOUtils.write(bytes, fos);
        IOUtils.closeQuietly(fos);
        IOUtils.closeQuietly(outputStream);
        System.out.println("===============success=================" );
    }

    private static List<Map<String, String>> queryColumns(String contest, String table) {
        String sql = "select * from information_schema.columns"
                + " where table_name = ? and table_schema = ? order by ordinal_position" ;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        List<Map<String, String>> columnDetails = new ArrayList<Map<String, String>>();
        try {
            conn = DriverManager.getConnection(url, username, password);
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, table);
            stmt.setString(2, contest);
            rs = stmt.executeQuery();
            while (rs.next()) {
                Map<String, String> columnMap = new HashMap<String, String>();
                String columnName = rs.getString("column_name" );
                String dataType = rs.getString("data_type" );
                String columnComment = rs.getString("column_comment" );
                String columnKey = rs.getString("column_key" );
                String extra = rs.getString("extra" );
                columnMap.put("columnName" , columnName);
                columnMap.put("dataType" , dataType);
                columnMap.put("columnComment" , columnComment);
                columnMap.put("columnKey" , columnKey);
                columnMap.put("extra" , extra);
                columnDetails.add(columnMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            releaseResource(conn, stmt, rs);

        }
        return columnDetails;
    }

    private static Map<String, String> queryTableDetailByTable(String schema, String table) {
        String sql = "select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables"
                + "	where table_schema = ? and table_name = ?" ;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Map<String, String> tableDetail = new HashMap<String, String>();
        try {
            conn = DriverManager.getConnection(url, username, password);
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, schema);
            stmt.setString(2, table);
            rs = stmt.executeQuery();
            while (rs.next()) {
                String tableName = rs.getString("tableName" );
                String tableComment = rs.getString("tableComment" );
                tableDetail.put("tableName" , tableName);
                tableDetail.put("tableComment" , tableComment);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            releaseResource(conn, stmt, rs);
        }
        return tableDetail;
    }

    /**
     * @return
     */
    private static List<String> queryAllTable(String schema) {

        DatabaseMetaData dbMetaData = null;
        ResultSet rs = null;
        List<String> tables = new ArrayList<String>();
        try {
            conn = DriverManager.getConnection(url, username, password);
            dbMetaData = conn.getMetaData();
            PreparedStatement preparedStatement = conn.prepareStatement("select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables where table_schema = ?");
            preparedStatement.setString(1,schema);
            rs=preparedStatement.executeQuery();
            //rs = dbMetaData.getTables(null, schema, "%" , new String[]{"TABLE"});
            while (rs.next()) {
//                String tableName = rs.getString("TABLE_NAME" );
                String tableName = rs.getString("tableName" );
                tables.add(tableName);
            }
            preparedStatement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            releaseResource(conn, null, rs);

        }
        return tables;
    }

    private static void releaseResource(Connection conn, PreparedStatement stmt, ResultSet rs) {
        try {
            if (rs != null) rs.close();
            if (stmt != null) stmt.close();
            if (conn != null) conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}